/** 
 * 基本的原始数据类型
 * boolean number string null undefined symbol bigint
 * @区别 区别于引用类型是Object 上的函数不可以被调用
 **/
const log = console.log.bind()
const boolean = true
const number = 1
const string = 'string'
const nullType = null
const undefinedType = undefined 
const symbol = Symbol('symbol')
const bigint = BigInt(1)
// 这里的number 其实被强制转换为了Number对象
// log(number.toString())
// 这里的null 和 undefined 会报错
// log(undefinedType.toString())
// null 为基本数据类型，但是typeof null 为object，这是因为在js的最初版本中使用的是32位系统，为了性能考虑使用低位存储了变量的类型信息，000开头代表是对象，然而null表示为全零，所以将它错误的判断为object
// log(typeof nullType)

// 手写typeof
const typeofFn = (target) => {
  const result =  Object.prototype.toString.call(target).slice(8, -1).toLowerCase()
  // 由于上面的方法超出里typeof的范围，所以需要手动判断如果是对象类型的话，需要进一步判断
  const baseTypeArr = ['boolean', 'number', 'string', 'symbol', 'bigint', 'undefined','function']
  return baseTypeArr.includes(result) ? result : 'object'
}

const diffLog = (a,b) => {
  log(a,b,a === b)
}

diffLog(typeofFn([]), typeof [])

/**
 * 对象类型
 */
// 手写instanceof
const myInstanceof = (left, right) => {
  if (typeof left !== 'object' || left === null) return false
  let proto = Object.getPrototypeOf(left)
  while(true) {
    if (proto === null) return false
    if (proto === right.prototype) return true
    proto = Object.getPrototypeOf(proto)
  }
}
diffLog(myInstanceof(Object.create({}), Object), {} instanceof Object)


export default diffLog